package com.glodon.paas.job.util;

import static com.glodon.paas.job.JobConstants.JOB_ID;
import static com.glodon.paas.job.JobConstants.PROPERTY_TASK_ID;
import static com.glodon.paas.job.JobConstants.PROPERTY_TASK_START_TIME;
import static com.glodon.paas.job.JobConstants.TASK_PROGRESS;
import static com.glodon.paas.job.model.TaskStatus.failure;
import static com.glodon.paas.job.model.TaskStatus.success;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import javax.jms.Message;

import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.usage.SystemUsage;
import org.apache.activemq.usage.TempUsage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.glodon.paas.job.model.MonitorEvent;
import com.glodon.paas.job.model.MonitorEventType;
import com.glodon.paas.job.model.Task;

public class JobUtil {

	private static final String	AGENT_ADDRESS			= "agent_address";
	private static final Logger	monitorLogger			= LoggerFactory.getLogger("monitor");
	private static final String	DEFAULT_TRANSPORT_URL	= "tcp://localhost:61616";

	public static BrokerService createEmbeddedActiveMq() throws Exception {
		return createEmbeddedActiveMq(DEFAULT_TRANSPORT_URL);
	}

	public static BrokerService createEmbeddedActiveMq(String transaportConnectorUrl) throws Exception {
		BrokerService brokerService = new BrokerService();
		SystemUsage usage = new SystemUsage();
		TempUsage tempUsage = new TempUsage();
		tempUsage.setLimit(40000000);
		usage.setTempUsage(tempUsage);
		brokerService.setSystemUsage(usage);
		brokerService.setPersistent(false);
		brokerService.setTransportConnectorURIs(new String[] { transaportConnectorUrl });
		brokerService.start();
		return brokerService;
	}

	public static Timestamp getMessageInTime(Message msg) {
		return new Timestamp(((org.apache.activemq.command.Message) msg).getBrokerInTime());
	}

	public static Timestamp getMessageOutTime(Message msg) {
		return new Timestamp(((org.apache.activemq.command.Message) msg).getBrokerOutTime());
	}

	private static String getJobId(Task task) {
		Object jobId = task.getValue(JOB_ID);
		return jobId != null ? ((String) jobId) : task.getTaskId();
	}

	public static void sendJobStatus(final Task task) {
		monitorLogger.info("send job status", new MonitorEvent() {
			{
				String agentAddress = getAddress();
				setType(MonitorEventType.JOB_STATUS);
				setTime(task.getNow());
				setTraceId(getJobId(task));
				setTraceIndex(true);
				addValue(TASK_PROGRESS, "0");
				addValue(PROPERTY_TASK_START_TIME, String.valueOf(task.getStartTime().getTime()));
				addValue(PROPERTY_TASK_ID, task.getTaskId());
				addValue("task", task.toJson());
				if (task.getStatus() == success) {
					setCmd("service.setStatusValue(context, 'agent_status', '" + agentAddress
							+ "', 'values[0].success = values[0].success + 1')");
				}
				if (task.getStatus() == failure) {
					setCmd("service.setStatusValue(context, 'agent_status', '" + agentAddress
							+ "', 'values[0].failure = values[0].failure + 1')");
				}
				addValue(AGENT_ADDRESS, agentAddress);
			}
		});
	}

	public static String getAddress() {
		Enumeration nets;
		try {
			nets = NetworkInterface.getNetworkInterfaces();
		} catch (SocketException se) {
			try {
				return InetAddress.getLocalHost().getHostAddress();
			} catch (UnknownHostException e) {
				return "UnknownHost";
			}
		}
		List<String> ipList = new ArrayList<String>();
		for (Object obj : Collections.list(nets)) {
			NetworkInterface netInterface = (NetworkInterface) obj;
			Enumeration addresses = netInterface.getInetAddresses();
			for (Object inetAdd : Collections.list(addresses)) {
				InetAddress inetAddress = (InetAddress) inetAdd;
				if (inetAddress instanceof Inet4Address) {
					String ip = inetAddress.getHostAddress();
					if (!ip.equalsIgnoreCase("127.0.0.1") && !ip.startsWith("10.")) {
						ipList.add(ip);
					}
				}
			}
		}
		StringBuilder builder = new StringBuilder();
		if (!ipList.isEmpty()) {
			for (int i = 0; i < ipList.size(); i++) {
				builder.append((String) ipList.get(i));
				if (i < ipList.size() - 1) {
					builder.append("|");
				}
			}
		} else {
			try {
				return InetAddress.getLocalHost().getHostAddress();
			} catch (UnknownHostException e) {
				return "UnknownHost";
			}
		}
		return builder.toString();
	}
}
